import { useUserStore } from '@/store/user'
import { GameObject } from '@/assets/scripts/GameObject'
import { Player } from '@/assets/scripts/Player'
import { useGameStore } from '@/store/game'
export class GameMap extends GameObject {
    constructor(ctx) {
        super()
        const userStore = useUserStore() // 获取用户store实例
        const gameStore = useGameStore() // 获取游戏store实例

        this.ctx = ctx
        // 保存游戏store引用，以便传递给子组件
        this.gameStore = gameStore
        // 设置地图大小为canvas大小
        this.width = this.ctx.canvas.width
        this.height = this.ctx.canvas.height

        // 游戏显示设置
        this.aspectRatio = { width: 16, height: 9 }
        this.sizeConfig = {
            playerRadius: 0.05, // 玩家半径占画面高度的比例
            playerSpeed: 0.15, // 玩家速度占画面高度的比例
        }

        this.players = []
        // 获取所有玩家信息
        const allPlayers = [{ userId: userStore.id, role: 'me', ...userStore }]

        // 添加对手信息 - 现在opponents是一个对象而不是数组
        if (gameStore.opponents.player1 && gameStore.opponents.player1.id) {
            allPlayers.push({
                userId: gameStore.opponents.player1.id,
                username: gameStore.opponents.player1.username,
                photo: gameStore.opponents.player1.photo,
            })
        }

        if (gameStore.opponents.player2 && gameStore.opponents.player2.id) {
            allPlayers.push({
                userId: gameStore.opponents.player2.id,
                username: gameStore.opponents.player2.username,
                photo: gameStore.opponents.player2.photo,
            })
        }

        // 按userId排序确保顺序一致
        allPlayers.sort((a, b) => {
            // 确保userId存在且为字符串
            const idA = String(a?.userId || '')
            const idB = String(b?.userId || '')
            return idA.localeCompare(idB)
        })

        // 计算三角形的位置坐标
        // 三角形的大小约为屏幕高度的1/3
        const triangleSize = this.height / 3.5

        // 三角形中心位于屏幕中心
        const centerX = this.width / 2
        const centerY = this.height / 2

        // 计算三角形的三个顶点位置
        const positions = [
            {
                // 顶部位置
                x: centerX,
                y: centerY - triangleSize * 0.866, // 0.866 = √3/2
            },
            {
                // 左下位置
                x: centerX - triangleSize / 2,
                y: centerY + triangleSize * 0.433, // 0.433 = √3/4
            },
            {
                // 右下位置
                x: centerX + triangleSize / 2,
                y: centerY + triangleSize * 0.433,
            },
        ]

        // 创建所有玩家
        for (let i = 0; i < allPlayers.length; i++) {
            const player = allPlayers[i]
            const position = i < positions.length ? positions[i] : positions[0]

            this.players.push(
                new Player(this, {
                    x: position.x,
                    y: position.y,
                    radius: this.height * this.sizeConfig.playerRadius,
                    color: player.role === 'me' ? 'white' : this.get_random_color(),
                    speed: this.height * this.sizeConfig.playerSpeed,
                    hp: 100,
                    role: player.role,
                    photo: player.photo,
                    username: player.username,
                    userId: player.userId,
                })
            )
        }

        this.resize()
    }
    // 生成一个随机颜色
    get_random_color() {
        let colors = ['red', 'blue', 'green', 'yellow', 'orange', 'purple', 'pink', 'brown', 'gray']
        return colors[Math.floor(Math.random() * colors.length)]
    }
    start() {}
    update() {
        this.render()
    }

    resize() {
        // 如果已标记为销毁，直接返回不执行任何操作
        if (this._destroyed) {
            return
        }

        // 检查画布和上下文是否有效
        if (!this.ctx || !this.ctx.canvas) {
            console.warn('GameMap上下文或画布无效，跳过resize操作')
            return
        }

        try {
            const canvas = this.ctx.canvas
            const oldWidth = this.width || canvas.width
            const oldHeight = this.height || canvas.height

            // 获取父容器尺寸
            const parent = canvas.parentElement
            if (!parent) {
                console.warn('画布没有父元素，跳过resize操作')
                return
            }

            const parentWidth = parent.clientWidth
            const parentHeight = parent.clientHeight

            // 计算基于比例的尺寸
            const unit = Math.min(
                parentWidth / this.aspectRatio.width,
                parentHeight / this.aspectRatio.height
            )

            // 设置canvas尺寸
            this.width = canvas.width = unit * this.aspectRatio.width
            this.height = canvas.height = unit * this.aspectRatio.height

            // 计算缩放比例
            const widthRatio = this.width / oldWidth
            const heightRatio = this.height / oldHeight

            // 更新玩家位置和属性
            if (this.players && this.players.length > 0) {
                for (let player of this.players) {
                    if (!player || !player.info) continue

                    try {
                        // 确保数值有效
                        if (isNaN(player.info.x) || isNaN(player.info.y)) {
                            console.warn(
                                `玩家${player.info.userId}位置无效: (${player.info.x}, ${player.info.y}), 重置为中心位置`
                            )
                            player.info.x = this.width / 2
                            player.info.y = this.height / 2
                        } else {
                            player.info.x *= widthRatio
                            player.info.y *= heightRatio
                        }

                        player.info.radius = this.height * this.sizeConfig.playerRadius
                        player.info.speed = this.height * this.sizeConfig.playerSpeed

                        player.width = this.width
                        player.height = this.height
                    } catch (e) {
                        console.error(`更新玩家${player.info.userId}属性时出错:`, e)
                    }
                }
            }

            // 更新其他游戏对象
            try {
                if (typeof GameObject.getObjects === 'function') {
                    const gameObjects = GameObject.getObjects()
                    if (!gameObjects || !Array.isArray(gameObjects)) {
                        console.warn('游戏对象列表无效，跳过对象更新')
                        return
                    }

                    const processedIds = new Set() // 用于跟踪已处理的对象
                    processedIds.add(this) // 添加当前GameMap实例

                    // 添加所有玩家到已处理集合
                    if (this.players) {
                        for (let player of this.players) {
                            if (player) processedIds.add(player)
                        }
                    }

                    // 创建一个已销毁GameMap的ID集合，用于快速查找
                    const destroyedMaps = new Set()
                    for (let obj of gameObjects) {
                        if (obj && obj._destroyed && obj instanceof GameMap) {
                            destroyedMaps.add(obj)
                        }
                    }

                    // 处理剩余对象
                    for (let obj of gameObjects) {
                        try {
                            // 严格验证对象有效性
                            if (!obj || typeof obj !== 'object') continue

                            // 跳过已处理的对象
                            if (
                                processedIds.has(obj) ||
                                (typeof Player !== 'undefined' && obj instanceof Player)
                            )
                                continue

                            // 增强的有效性检查
                            if (obj.gameMap) {
                                // 1. 检查gameMap是否被销毁
                                if (obj.gameMap._destroyed || destroyedMaps.has(obj.gameMap)) {
                                    console.warn('对象引用了已销毁的GameMap，跳过调整大小')

                                    // 清除引用以防止内存泄漏
                                    try {
                                        if (typeof obj.destroy === 'function') {
                                            obj.destroy()
                                        } else {
                                            obj.gameMap = null
                                        }
                                    } catch (e) {
                                        console.warn('清除无效引用时出错:', e)
                                    }
                                    continue
                                }

                                // 2. 检查gameMap是否是当前GameMap的实例
                                if (obj.gameMap !== this) {
                                    // 对象属于其他地图实例，跳过
                                    continue
                                }
                            }

                            // 安全地调用对象的resize方法
                            if (typeof obj.resize === 'function') {
                                obj.resize(widthRatio, heightRatio)
                            }

                            // 标记为已处理
                            processedIds.add(obj)
                        } catch (err) {
                            console.error('处理特定对象时出错:', err, obj)
                        }
                    }
                }
            } catch (error) {
                console.error('处理游戏对象时出错:', error)
            }
        } catch (error) {
            console.error('GameMap.resize方法执行出错:', error)
        }
    }
    // 标记玩家死亡 - 完全由后端控制，前端只负责显示
    player_is_killed(player) {
        if (!player || !player.info) {
            console.error('GameMap.player_is_killed收到无效的玩家对象')
            return
        }

        // 确保is_dead标志被设置为true
        player.is_dead = true

        // 确保血量设置为0
        player.info.hp = 0
    }

    // 处理玩家死亡的回调函数
    playerDeath(player) {
        // 检查参数有效性
        if (!player || !player.info) {
            console.error('GameMap.playerDeath收到无效的玩家对象')
            return
        }

        // 防止重复处理
        if (player.is_dead) {
            return
        }

        // 标记玩家死亡
        this.player_is_killed(player)

        // 注意：不再向后端发送死亡事件
        // 仅进行本地UI更新，死亡事件由后端控制
    }

    // 处理后端发送的玩家移动消息
    handlePlayerMove(data) {
        // 检查是否是已销毁的GameMap
        if (this._destroyed) {
            console.warn('GameMap已被销毁，无法处理玩家移动')
            return
        }

        try {
            // 查找要移动的玩家
            const player = this.players.find((p) => p.info.userId === data.userId)

            // 只处理存在且不是当前玩家自己的移动 (且玩家未死亡)
            if (player && !player.is_dead) {
                // 注意：这里移除了is_me检查，允许处理所有玩家的移动消息
                // 将比例坐标转换为实际坐标
                const actualX = data.x * this.width
                const actualY = data.y * this.height
                const actualTx = data.tx * this.width
                const actualTy = data.ty * this.height

                // 更新玩家位置
                player.info.x = actualX
                player.info.y = actualY

                // 设置移动目标
                player.move_to(actualTx, actualTy)
            } else if (!player) {
                console.warn(`找不到ID为${data.userId}的玩家，无法处理移动`)
            } else if (player.is_dead) {
                console.warn(`玩家${data.userId}已死亡，忽略移动消息`)
            }
        } catch (error) {
            console.error('处理玩家移动消息时出错:', error)
        }
    }

    // 处理后端发送的火球消息 - 只在前端显示火球效果
    handlePlayerShootFireball(data) {
        try {
            // 找到发射火球的玩家
            const player = this.players.find((p) => p.info.userId === data.userId);
            
            // 确保玩家存在且未死亡
            if (!player || player.is_dead) {
                console.warn(`无法找到玩家 ${data.userId} 或玩家已死亡, 跳过火球创建`);
                return;
            }

            // 将比例坐标转换为实际坐标
            const actualX = data.x * this.width;
            const actualY = data.y * this.height;
            const actualTx = data.tx * this.width;
            const actualTy = data.ty * this.height;

            // 先立即同步当前位置
            player.info.x = actualX;
            player.info.y = actualY;

            // 确保玩家有技能系统
            if (!player.skills) {
                player.initialize_skills();
            }

            // 发射火球 - 首先检查shoot_fireball方法是否存在
            if (typeof player.shoot_fireball === 'function') {
                try {
                    player.shoot_fireball(actualTx, actualTy);
                } catch (error) {
                    console.error(`创建火球时出错:`, error);
                }
            } else {
                console.error(`玩家 ${data.userId} 缺少shoot_fireball方法`);
                
                // 尝试直接使用fireball技能
                if (player.skills && player.skills.fireball) {
                    try {
                        // 计算方向向量
                        const angle = Math.atan2(actualTy - actualY, actualTx - actualX);
                        const vx = Math.cos(angle);
                        const vy = Math.sin(angle);
                        
                        // 如果有createFireballEntity方法，直接调用
                        if (typeof player.skills.fireball.createFireballEntity === 'function') {
                            player.skills.fireball.createFireballEntity(vx, vy);
                        } else {
                            console.warn(`玩家 ${data.userId} 的fireball技能缺少createFireballEntity方法`);
                        }
                    } catch (e) {
                        console.error(`尝试直接创建火球时出错:`, e);
                    }
                }
            }
        } catch (error) {
            console.error(`处理火球消息时出错:`, error);
        }
    }

     // 联机模式处理玩家闪现
    handle_player_flash(data) {
        try {
            // 查找玩家
            const player = this.players.find((p) => p.info.userId === data.userId)
            if (!player || player.is_dead) {
                console.warn(`无法找到玩家 ${data.userId} 或玩家已死亡, 跳过闪现处理`)
                return
            }

            // 将比例坐标转换为实际坐标
            const actualX = data.x * this.width
            const actualY = data.y * this.height
            const actualTx = data.tx * this.width
            const actualTy = data.ty * this.height

            // 立即同步当前位置
            player.info.x = actualX
            player.info.y = actualY

            // 确保玩家有技能系统
            if (!player.skills) {
                player.initialize_skills()
            }

            // 如果服务器提供了实际落点坐标，直接使用
            if (data.newX !== undefined && data.newY !== undefined) {
                const finalX = data.newX * this.width
                const finalY = data.newY * this.height

                // 计算闪现距离和角度
                const distance = Math.sqrt((finalX - actualX) ** 2 + (finalY - actualY) ** 2)
                const angle = Math.atan2(finalY - actualY, finalX - actualX)

                // 创建闪现效果
                if (player.skills && player.skills.flash) {
                    player.skills.flash.create_flash_effect(angle, distance)
                }

                // 直接设置最终位置
                player.info.x = finalX
                player.info.y = finalY
                player.move_length = 0
            } else {
                // 如果服务器没有提供落点，使用本地计算
                if (player.skills && player.skills.flash) {
                    player.skills.flash.cast(actualTx, actualTy)
                }
            }
        } catch (error) {
            console.error('处理闪现事件时出错:', error)
        }
    }

    // 联机模式处理玩家治疗术
    handle_player_heal(data) {
        try {
            // 查找玩家
            const player = this.players.find((p) => p.info.userId === data.userId)
            if (!player || player.is_dead) {
                console.warn(`无法找到玩家 ${data.userId} 或玩家已死亡, 跳过治疗处理`)
                return
            }

            // 确保玩家有技能系统
            if (!player.skills) {
                player.initialize_skills()
            }

            // 如果服务器提供了新的血量，更新玩家血量
            if (data.hp !== undefined) {
                player.info.hp = data.hp
            } else if (data.amount !== undefined) {
                // 根据治疗量增加血量，但不超过最大值
                player.info.hp = Math.min(player.maxHp, player.info.hp + data.amount)
            }

            // 创建治疗效果
            if (player.skills && player.skills.heal) {
                // 创建视觉效果
                player.skills.heal.create_heal_effect()
                
                // 如果服务器提供了冷却时间信息，重置技能冷却
                if (data.cooldownMs !== undefined) {
                    // 强制重置冷却时间
                    player.skills.heal.lastCastTime = new Date().getTime()
                    // 确保技能回到冷却状态
                    player.skills.heal.remainingCooldown = data.cooldownMs
                }
            }
        } catch (error) {
            console.error('处理治疗事件时出错:', error)
        }
    }

    // 处理治疗冷却状态消息
    handle_heal_cooldown(data) {
        try {
            // 本地玩家的冷却处理
            const player = this.players.find(p => p.info.role === 'me')
            if (!player || !player.skills || !player.skills.heal) {
                return
            }
            
            // 如果有剩余冷却时间信息，更新本地冷却状态
            if (data.remaining !== undefined) {
                const remainingMs = data.remaining * 1000
                const currentTime = new Date().getTime()
                
                // 更新上次施放时间，使其符合剩余冷却时间
                player.skills.heal.lastCastTime = currentTime - (player.skills.heal.cooldown - remainingMs)
                player.skills.heal.remainingCooldown = remainingMs
                
                console.log(`治疗技能冷却中，剩余时间: ${data.remaining.toFixed(1)}秒`)
            }
        } catch (error) {
            console.error('处理治疗冷却状态消息时出错:', error)
        }
    }

    render() {
        this.ctx.fillStyle = 'rgba(0, 0, 0, 0.05)'
        this.ctx.fillRect(0, 0, this.width, this.height)
    }
    // 添加从玩家列表中移除玩家的方法
    removePlayer(player) {
        const index = this.players.findIndex((p) => p === player)
        if (index !== -1) {
            this.players.splice(index, 1)
        }
    }
    // 在GameMap类中添加销毁方法
    onDestroy() {
        // 强制销毁所有关联对象
        const gameObjects = GameObject.getObjects()
        gameObjects.forEach((obj) => {
            if (obj !== this && obj.gameMap === this) {
                obj.destroy()
            }
        })

        // 清理玩家列表
        for (let i = this.players.length - 1; i >= 0; i--) {
            this.players[i].destroy()
        }
        this.players = []

        // 清除画布引用
        this.ctx = null
        this.gameStore = null
    }
}
